package com.kylin.common.security.config;

import com.kylin.common.core.filter.ApiLogFilter;
import com.kylin.common.security.filter.JwtLoginAuthenticationFilter;
import com.kylin.common.security.filter.JwtTokenAuthenticationFilter;
import com.kylin.common.security.filter.TenantFilter;
import com.kylin.common.security.provider.CustomAuthenticationProvider;
import com.kylin.common.security.service.CaptchaService;
import com.kylin.common.security.service.UserDetailsServiceImpl;
import com.kylin.common.security.service.handler.LoginHandlerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.security.web.session.DisableEncodeUrlFilter;
import org.springframework.stereotype.Component;

/**
 * httpSecurity详细配置
 * @author wuhao
 * @version 1.0 - 2022/10/6
 */
@Component
public class HttpSecurityConfig extends AbstractHttpConfigurer<HttpSecurityConfig, HttpSecurity> {

    @Autowired
    private UserDetailsServiceImpl userDetailsService;
    @Autowired
    private CaptchaService captchaService;
    @Autowired
    private SecurityProperties securityProperties;
    @Autowired
    LoginHandlerFactory loginHandlerFactory;

    @Autowired
    private ApplicationContext applicationContext;

    @Override
    public void configure(HttpSecurity builder) {

        // 1. 初始化自定义登录处理器 AuthenticationFilter
        JwtLoginAuthenticationFilter filter = new JwtLoginAuthenticationFilter(captchaService,securityProperties, loginHandlerFactory);
        filter.setAuthenticationManager(builder.getSharedObject(AuthenticationManager.class));

        // 2. 初始化自定义AuthenticationProvider
        CustomAuthenticationProvider provider = new CustomAuthenticationProvider();
        provider.setUserDetailsService(userDetailsService);

        // 3. 将设置完毕的 Filter 与 Provider 添加到配置中，将自定义的登录Filter 加到 UsernamePasswordAuthenticationFilter 之前
        builder.authenticationProvider(provider).addFilterBefore(filter, LogoutFilter.class);

        // 4.自定义认证处理
        builder.addFilterBefore(new JwtTokenAuthenticationFilter(securityProperties), LogoutFilter.class);

        // 添加全局日志拦截
        builder.addFilterBefore(new ApiLogFilter(), DisableEncodeUrlFilter.class);

        // 租户拦截器
        if(applicationContext.containsBean("tenantFilter")) {
            TenantFilter tenantFilter = applicationContext.getBean(TenantFilter.class);
            builder.addFilterBefore(tenantFilter, DisableEncodeUrlFilter.class);
        }

    }
}
